<?php
/* *【主站使用】
 * 功能：支付宝服务器异步通知页面
 * 版本：3.3
 * 日期：2012-07-23
 * 说明：
 * 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 * 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。


 *************************页面功能说明*************************
 * 创建该页面文件时，请留心该页面文件中无任何HTML代码及空格。
 * 该页面不能在本机电脑测试，请到服务器上做测试。请确保外部可以访问该页面。
 * 该页面调试工具请使用写文本函数logResult，该函数已被默认关闭，见alipay_notify_class.php中的函数verifyNotify
 * 如果没有收到该页面返回的 success 信息，支付宝会在24小时内按一定的时间策略重发通知
 */
namespace api\controllers;

use leyestd\alipay\lib\AlipayNotify;
use leyestd\alipay\Aliconfig;
use Yii;
use Opwechat\Phppayment\CLogFileHandler;
use Opwechat\Phppayment\Log;
use services\models\OrderInfo;
use services\models\Order;
use services\models\PayLog;


class NotifyAlipayController extends BaseCoreController 
{
    public $alipay_config = '';
    public $path='';
    //关闭layout已经安全模式
    public function init(){
        parent::init();
        $this->alipay_config = (new Aliconfig())->getAliconfig();
        $this->path = Yii::$app->params['root_log'];
        
    }
    
    public function actionIndex() {
        //初始化日志
        $logHandler= new CLogFileHandler($this->path."/alipay/notify_".date('Y-m-d').'.log');
        $log = Log::Init($logHandler, 15);
        
        //计算得出通知验证结果
        $alipayNotify = new AlipayNotify($this->alipay_config);
        $verify_result = $alipayNotify->verifyNotify();
        
        Log::DEBUG('begin-notify');
        if($verify_result) 
        {
            $data = Yii::$app->request->post();
            //记录日志
            Log::INFO(json_encode($data));
            
            $out_trade_no = $data['out_trade_no']; //商户订单号
            $trade_no = $data['trade_no']; //支付宝交易号
            $trade_status = $data['trade_status']; //交易状态
            $total_fee =  $data['total_fee'];// 交易金额
            $notify_time = $data['notify_time']; // 通知时间
            $bank_seq_no = Yii::$app->request->post('bank_seq_no','');// 网银流水号
            $out_channel_type = Yii::$app->request->post('out_channel_type','');// 支付渠道组合信息
            $out_channel_inst = Yii::$app->request->post('out_channel_inst','');// 实际支付渠道
            
            if($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') 
            {
                //查询订单信息
                $order_info = OrderInfo::find()->select(['bestry_uid','status','pay_status','order_amount','order_info_id'])->where(['order_sn'=>$out_trade_no])->one();
                if(empty($order_info)) {
                    Log::DEBUG('select order_info:'.$out_trade_no.'查询不到订单信息');
                    exit;
                } 
                
                $flag = false;
                // 如果是已经取消的订单，再支付，只更新支付状态，不更新订单状态
                if(!empty($order_info) && $order_info->status == OrderInfo::$STATUS_ORDER_CANCEL  && $order_info->pay_status == OrderInfo::$PAY_STATUS_WAIT) {
                    //插入日志
                    Log::DEBUG($out_trade_no.'是已取消订单，开始修改支付状态，不修改订单状态');
                    //开始修改订单状态
                    $flag = Order::orderStatusChange($order_info->order_info_id, $order_info->status,OrderInfo::$PAY_STATUS_SUCCESS);
                }
                
                // 如果是待支付状态，更新订单状态，支付状态。
                if(!empty($order_info) &&  $order_info->status  == OrderInfo::$STATUS_ORDER_CREATED && $order_info->pay_status == OrderInfo::$PAY_STATUS_WAIT) {
                     
                    //插入日志
                    Log::DEBUG($out_trade_no.'是待支付订单，开始修改支付状态，修改订单状态');
                
                    $flag = Order::orderStatusChangePayed($order_info->order_info_id);
                }
                //更新订单成功后插入pay_log记录
                if($flag === true) {
                    //插入支付日志
                    Log::DEBUG($out_trade_no.'开始插入支付pay_log');
                    $this->updatePayLog($order_info->order_info_id,$out_trade_no,$trade_status,$trade_no='',$notify_time,$bank_seq_no='',$out_channel_type='',$out_channel_inst='');
                
                }
            } else {
                Log::DEBUG("trade_status=".$trade_status);
                echo "trade_status=".$trade_status;
            }
            
        } else 
        {
            Log::ERROR('Validation failure');
            echo "fail";
            
        }
    }
    
    /**
     * 修改支付pay_log
     * @param int $order_info_id 订单id
     * @param string $out_trade_no 订单号
     * @param unknown $trade_status 支付状态
     * @param unknown $trade_no 支付宝交易流水号
     * @param unknown $notify_time 通知时间
     * @param unknown $bank_seq_no 网银流水号
     * @param unknown $out_channel_type 该笔交易所使用的支付渠道
     * @param unknown $out_channel_inst 实际支付渠道
     */
    private function updatePayLog($order_info_id,$out_trade_no,$trade_status,$trade_no='',$notify_time,$bank_seq_no='',$out_channel_type='',$out_channel_inst=''){
        $model = PayLog::findOne(['order_info_id'=>$order_info_id,'order_sn'=>$out_trade_no]);
        if($model) {
                $model->trade_status   = $trade_status;
                $model->trade_no        = $trade_no;
                $model->notify_time     = $notify_time;
                $model->bank_seq_no     = $bank_seq_no;
                $model->out_channel_type = $out_channel_type;
                $model->out_channel_inst = $out_channel_inst;
                $model->save();
                return true;
        
            }else {
                
                Log::WARN($out_trade_no.'在pay_log表未查询到记录');
        
                return false;
            }
        
    }
    
}

?>